﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using System.Web;
using System.Data;
using System.IO;
using System.Configuration;
using System.Transactions;
using System.Data.Linq;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Linq.Expressions;
using UtilityExtensions;

namespace BOL
{ 
[Serializable]
    public class ComparativoBL
    {
        public int add(int idEstructuraCosto,
                                    DateTime fecha,
                                    string descripcion,
                                    string observacion,
                                    int idObra,
                                    int idMoneda,
                                    int idProveedorSeleccion,
//                                    bool OCregularizado,
                                    List<ComparativoItemInfo> entityList,
                                   List<ComparativoProveedorInfo> comparativoProveedor)
        {



            using (TransactionScope ts = new TransactionScope())
            {
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                //--------------------
                bool acceso=new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    2,
                    idObra,
                     2);
                //-------------------------            
                
                if (comparativoProveedor.Count() == 1)
                {
                    //uno po que el 0 como registro vacio
                    throw new Exception("Ingrese Proveedor");
                }
                if (entityList.Count() == 0)
                {
                    throw new Exception("Ingrese Recursos del Comparativo");
                }
                if (descripcion.Trim().Length == 0)
                {
                    throw new Exception("Ingrese descripcion del Comparativo");
                }
                
                Comparativo dbc = new Comparativo();
                List<ComparativoItemInfo> compartivoItemList = new List<ComparativoItemInfo>();

                //---14/03/2012-----------actualizacion del tipocambio del comparativo , este es el tipo de cambio de la obra
                decimal tipoCambio=1;
                if (idMoneda==4)
                {
                tipoCambio=_db.Obras.Single(p=>p.idInternal==idObra).tipoCambio.Value;
                }
                

                dbc.add(_db,
                    idEstructuraCosto,
                    fecha,
                    descripcion,
                    tipoCambio,
                    observacion,
                    idProveedorSeleccion,
                    idObra,
                    idMoneda,
                    idEmpleadoEmisor);


                //en el mismo comparativo no debe existir el mismo Item

                int totalsinRepetir = entityList.Select(p => p.idEstructuraCostoItem).Distinct().Count();
                int totalRegistros = entityList.Count;
                if (totalRegistros != totalsinRepetir)
                {
                    throw new Exception("Existe items Repetidos ,verifique ");
                }
                   // necesario para los que bienen del con OC
                   List<ComparativoItemSelecInfo> lis=new List<ComparativoItemSelecInfo>();

                foreach (var item in entityList)
                {
                    ComparativoItem r = new ComparativoItem();

                    if (item.idEstructuraCostoItem == 0)
                    {
                        continue;
                    }
                    // verificar que el control sea el mismo en todos los comparativos por  item del ECITEM
                   

                    if (Math.Round(item.total1,2) == 0.00m & (comparativoProveedor.Count()>=2)
                        | Math.Round(item.total2, 2) == 0.00m & (comparativoProveedor.Count() >= 3)
                        | Math.Round(item.total3, 2) == 0.00m & (comparativoProveedor.Count() >= 4)) 
                        
                    {
                        
                            throw new Exception("No se permite Recursos con totales en 0, verifique:{0}".Fmt(item.descripcion));
                        
                    }

                    //el tipo de cambio utilizado en los item  , es diferente para contener el calculo correcto para la estructura
                    // de compras.

                    r.addItem(_db,
                        dbc.idInternal,
                        item.idEstructuraCostoItem,
                        item.bitControlCant,
                        item.codigo,
                        item.descripcion,
                        item.unidad,
                        0,
                        null,
                        item.cantidadBase,
                        item.precioBase,
                        item.cantidadOrig,
                        item.totalBaseOrig,
                        item.tipoCambioOrig,
                        item.totalComparar,
                        idMoneda,
                        item.precio1,
                        item.total1,
                        item.precio2,
                        item.total2,
                        item.precio3,
                        item.total3,
                        true,
                        item.tipoCambio,
                        dbc.idAudit);

                        
                   
                }


                int idProveedorSele = 0;
                
                //totalizar subtotales
                // registramos la  seleccionados proveedores
                short ss = 0;
                foreach (var pro in comparativoProveedor)
                {
                    if (pro.idInternal == 0)
                    { continue; }
                    ss++;

                    ComparativoProveedor cp = new ComparativoProveedor();

                    //segun el registrado en el comparativo
                                       

                            int idComparativoProveedor = cp.addProveedor(_db,
                                            dbc.idInternal,
                                            pro.idProveedor,
                                            ss,
                                            pro.condicion,
                                            0,
                                            dbc.idMoneda.Value,
                                            pro.idFormaPago,
                                            tipoCambio);

                            if (pro.idProveedor == idProveedorSeleccion)
                            {
                                idProveedorSele = idComparativoProveedor;
                            }
                    
                    cp.updateMonto(_db);
                    }
               
                dbc.updateTotalComparativo(_db);
                
                this.updateTotalContratadoProveddor(_db, dbc.idInternal, idProveedorSele);
                //enparejamos las ordenes de compra

                this.UpdateOCSinComparativo(_db, dbc.idInternal, idProveedorSele);
               

                ts.Complete();
                return dbc.idInternal;
            }

        }


        //public void addFromOrdenCompra(int idEstructuraCosto,
        //                                DateTime fecha,
        //                                string descripcion,
        //                                string observacion,
        //                                int idObra,
        //                                List<int> OrdenCompraList)
        //{
        //    using (TransactionScope ts = new TransactionScope())
        //    {
        //        dbGestionDataContext _db =
        //            new dbGestionDataContext(Parametros.strConnString);

        //        int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
        //        //--------------------
        //        bool acceso = new FormularioAcceso().VerificarAcceso(_db,
        //            idEmpleadoEmisor,
        //            2,
        //            idObra,
        //             2);
        //        //-------------------------            


        //        if (OrdenCompraList.Count() == 1)
        //        {
        //            //uno po que el 0 como registro vacio
        //            throw new Exception("Ingrese Proveedor");
        //        }

        //        foreach (var item in OrdenCompraList)
        //        {
        //            var OrdenCompra = _db.OrdenCompras.Single(p => p.idInternal == item);
        //            var comparativoItemInfo=new ComparativoItemInfo();
                    
        //            comparativoItemInfo


        //               List<ComparativoItemInfo> entityList


        //        }
        //    }
        //}


        public bool update(int idComparativo,
                                DateTime fecha,
                                string descripcion,
                                int idMoneda,
                                string observacion,
                                DataSet entityList)
        {
            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                DataSet dsDiferencias = new DataSet();

                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);

                //------------------------------------------
                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    2,
                    comparativo.idObra.Value,
                    3);

                //-------------------------------------------

              
                if (comparativo.idEstado != 1)
                {
                    throw new Exception("No puede  Editar el comparativo por estar Aprobado");

                }


                //---14/03/2012-----------actualizacion del tipocambio del comparativo , este es el tipo de cambio de la obra
                decimal tipoCambio = 1;
                if (idMoneda == 4)
                {
                    tipoCambio = _db.Obras.Single(p => p.idInternal == comparativo.idObra).tipoCambio.Value;
                }
                

                comparativo.update(_db,
                    fecha,
                    descripcion,
                    idMoneda,
                    tipoCambio,
                    observacion,
                    idEmpleadoEmisor);

          
                if (entityList.HasChanges())
                {
                    dsDiferencias.Merge(entityList.GetChanges());

                  

                    foreach (DataRow drw in dsDiferencias.Tables["ComparativoItemInfo"].Rows)
                    {

                        if (drw.RowState == DataRowState.Modified)
                        {
                            ComparativoItem cp = _db.ComparativoItems.Single(p => p.idInternal == drw.Field<int>("IdInternal"));


                            ////sin uso entonces se elimna

                            if (cp.totalUso > 0)
                            {
                                throw new Exception("no puede Modificar por estar en uso en la Orden de Compra");
                            }


                            cp.updateItem(_db,
                                            drw.Field<bool>("bitControlCant"),
                                            drw.Field<decimal>("cantidadBase"),
                                            drw.Field<decimal>("precioBase"),
                                            drw.Field<decimal>("cantidadOrig"),
                                            drw.Field<decimal>("totalBaseOrig"),
                                            drw.Field<decimal>("totalBase"),
                                            idMoneda,
                                            drw.Field<decimal>("precio1"),
                                            drw.Field<decimal>("total1"),
                                            drw.Field<decimal>("precio2"),
                                            drw.Field<decimal>("total2"),
                                            drw.Field<decimal>("precio3"),
                                            drw.Field<decimal>("total3"),
                                            drw.Field<decimal>("tipoCambio"),
                                            comparativo.idAudit);
                            _db.SubmitChanges();

                        }
                        if (drw.RowState == DataRowState.Deleted)
                        {
                            drw.RejectChanges();
                            ComparativoItem cp = _db.ComparativoItems.Single(p => p.idInternal == drw.Field<int>("IdInternal"));

                            if (cp.totalUso > 0)
                            {
                                throw new Exception("no puede Eliminar por estar en uso en la Orden de Compra:"+cp.codigo+"-"+cp.descripcion);
                            }
                            cp.deleteItem(_db,
                            comparativo.idAudit);


                        }

                        if (drw.RowState == DataRowState.Added)
                        {

                            ComparativoItem r = new ComparativoItem();



                            r.addItem(_db,
                                comparativo.idInternal,
                                drw.Field<int>("idEstructuraCostoItem"),
                                drw.Field<bool>("bitControlCant"),
                                drw.Field<string>("codigo"),
                                drw.Field<string>("descripcion"),
                                drw.Field<string>("unidad"),
                                drw.Field<int>("nivel"),
                                null,
                                drw.Field<decimal>("cantidadBase"),
                                drw.Field<decimal>("precioBase"),
                                drw.Field<decimal>("cantidadOrig"),
                                drw.Field<decimal>("totalBaseOrig"),
                                drw.Field<decimal>("tipoCambioOrig"),
                                drw.Field<decimal>("totalBase"),
                                idMoneda,
                                drw.Field<decimal>("precio1"),
                                drw.Field<decimal>("total1"),
                                drw.Field<decimal>("precio2"),
                                drw.Field<decimal>("total2"),
                                drw.Field<decimal>("precio3"),
                                drw.Field<decimal>("total3"),
                                true,
                                drw.Field<decimal>("tipoCambio"),
                                comparativo.idAudit);

                        }

                        //al editar tiene que volver a seleccion el Proveedor

                    }

                }
                // -----------------------Calculamos de saldos de contratado segun el proveedor

                var q = from a in _db.ComparativoProveedors
                        where a.idComparativo == idComparativo & a.bitSeleccion==true
                        select a;

                if (q.Count() > 0)
                {
                    updateTotalContratadoProveddor(_db, idComparativo, q.First().idinternal);
                }

                
                //-----------------------------------------------------------

                foreach (DataRow drw in dsDiferencias.Tables["ComparativoProveedorInfo"].Rows)
                {

                    if (drw.RowState == DataRowState.Modified)
                    {
                        ComparativoProveedor cp =
                            _db.ComparativoProveedors.Single(
                            p => p.idinternal == drw.Field<int>("IdInternal"));

                        cp.updateProveedor(_db,
                                            drw.Field<int>("idProveedor"),
                                            drw.Field<string>("condicion"),
                                            drw.Field<decimal>("total"),
                                            comparativo.idMoneda.Value,
                                            drw.Field<int>("idFormaPago"),
                                            drw.Field<decimal>("tipoCambio"));

                        decimal total = cp.getMontoTotal(_db);
                        cp.total = total;
                        _db.SubmitChanges();

                    }


                    if (drw.RowState == DataRowState.Added)
                    {
                        ComparativoProveedor cp = new ComparativoProveedor();
                        short ss = 0;

                        var qqq = (from a in _db.ComparativoProveedors.Where(p => p.idComparativo == idComparativo)
                                 select a);
                        if (qqq.Count() > 0)
                        {
                            ss = short.Parse(qqq.Count().ToString());

                        }
                        ss++;


                        cp.addProveedor(_db,
                                idComparativo,
                                drw.Field<int>("idProveedor"),
                                short.Parse(ss.ToString()),
                                drw.Field<string>("condicion"),
                                0,
                                comparativo.idMoneda.Value,
                                drw.Field<int>("idFormaPago"),
                                tipoCambio);

                        decimal total = cp.getMontoTotal(_db);
                        cp.total = total;
                        _db.SubmitChanges();

                    }

                }
                comparativo.updateTotalComparativo(_db);
                //---para el caso que descarque el total base uso del comparativo

                this.UpdateOCSinComparativo(_db, 
                                        comparativo.idInternal, 
                                        comparativo.idProveedorSelec.Value);

                ts.Complete();
                result = true;
            }
            return result;
        }


        public bool delete(int idComparativo)
        {

            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {

                dbGestionDataContext _db;
                _db = new dbGestionDataContext(Parametros.strConnString);

                Comparativo dbObject = _db.Comparativos.Single(p => p.idInternal == idComparativo);

                //------------------------------------------
                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                bool acceso = new FormularioAcceso().VerificarAcceso(_db,
                    idEmpleadoEmisor,
                    2, //comparativo
                    dbObject.idObra.Value,
                    4); //4 completo

                //----------------------------------------------------------

                var q = from a in _db.OrdenCompras
                        where a.idComparativo == idComparativo
                        select a;

                    if (q.Count() > 0)
                    {
                        throw new Exception(" No puede eliminar por existir Ordenes de compra."+
                            "Verifique tambien las Ordenes de Compra Anuladas");
                    }

                int idEC = dbObject.idEstructuraCosto.Value;
                var det = from r in _db.ComparativoItems
                          where r.idComparativo == idComparativo
                          select r;
               
                // ELIMINAMOS LOS REGISTROS DE itemproveedorSeleccion
               
                var pis = from a in _db.ComparativoItemSelecPrv
                          where a.ComparativoItem.idComparativo == idComparativo
                          select a;

                _db.ComparativoItemSelecPrv.DeleteAllOnSubmit(pis);
                _db.ComparativoItems.DeleteAllOnSubmit(det);

                _db.ComparativoProveedors.DeleteAllOnSubmit(dbObject.ComparativoProveedors);

                _db.Comparativos.DeleteOnSubmit(dbObject);
                _db.SubmitChanges();
                //Actualizamos los valores de estructura de costo
                //por cada item del comparativo se actualiza la EC
                // siempre en cuando  exista Aprobacion
                EstructuraCosto EC = _db.EstructuraCostos.Single(p => p.idInternal == idEC);
                EC.updateUsoFromComparativo(_db);

                //foreach (var r in intdetCEItem)
                //{
                //    EstructuraCostoItem ECItem = _db.EstructuraCostoItems.Single(p => p.idInternal == r);

                //    ECItem.totalUso = ECItem.getMontoUsoTotalComparativoItem(_db, ECItem.idInternal);
                //    ECItem.cantidadUso = ECItem.getCantidadUsoTotalComparativoItem(_db, ECItem.idInternal);
                //    _db.SubmitChanges();
                //}


                //EC.montoUso = EC.getMontoUsoTotal(_db, EC.idInternal);
                //_db.SubmitChanges();
                ts.Complete();
                result = true;
            }
            return result;

        }

        //public bool updateProveedorSeleccion(dbGestionDataContext _db, int idComparativo, int idCompaProveedor)
        //{
        //    //idcomparativoProveedor es el  internalid de la tabla


        //    bool result = false;
        //    using (TransactionScope ts = new TransactionScope())
        //    {
        //        result = updateTotalContratadoProveddor(_db, idComparativo, idCompaProveedor);
        //        ts.Complete();
        //        return result;
        //    }
        //}



    public void UpdateOCSinComparativo(dbGestionDataContext _db,
                                      int   idComparativo,
                                      int idComparativoSeleccion)
    {


           ///ECtem 1  a 1 compItem   no debe existir devolucion
           ///
         
         var q = from a in _db.ComparativoItems
                 where a.idComparativo==idComparativo
                 & a.EstructuraCostoItem.idOrdenCompraItemRef != null
                 select new
                 {
                     idOrdenCompraItem = a.EstructuraCostoItem.idOrdenCompraItemRef.Value,
                     idComparativoItem = a.idInternal
                 };

                 foreach (var item in q)
                 {
                     var ordenCompraItem = _db.OrdenCompraItems.Single(p => p.idInternal == item.idOrdenCompraItem);
                     var ordenCompra = ordenCompraItem.OrdenCompra;

                     var comparativoSelectProv = _db.ComparativoItemSelecPrv.Single(p => p.idComparativoItem == item.idComparativoItem & p.idComparativoProv == idComparativoSeleccion);

                     ordenCompraItem.SetUpdateComparativoSelectProv(comparativoSelectProv.idInternal);
                     ordenCompra.idComparativo = idComparativo;
                     ordenCompra.idProveedorSelec = idComparativoSeleccion;
                     _db.SubmitChanges();
             
                 }

        
    }
                        


        public bool updateTotalContratadoProveddor(dbGestionDataContext _db,
            int idComparativo, 
            int idCompaProveedor)
        {
            //idcomparativoProveedor es el  internalid de la tabla


            bool result = false;
            using (TransactionScope ts = new TransactionScope())
            {
                
                //Comparativo comparativo =
                //    _db.Comparativos.Single(p => p.idInternal == idComparativo);

                
                ComparativoProveedor comparativoProveedor =
                    _db.ComparativoProveedors.Single(p => p.idinternal == idCompaProveedor);

                //actualiza el bit de seleccion
                comparativoProveedor.UpdateProveedorSeleccion(_db,
                                                            comparativoProveedor.idComparativo.Value,
                                                                            idCompaProveedor);

                // actualiza sus totales;

                var q = from i in _db.ComparativoItems
                        where i.idComparativo == idComparativo & i.bitSel == true
                        select i;


                foreach (var i in q)
                {
                    var cpa = from a in _db.ComparativoItemSelecPrv
                              where a.idComparativoItem == i.idInternal
                              select a;

                    List<ComparativoItemSelecPrv> list = cpa.ToList();

                    //Limpiamos registros basura
                    foreach (var a in list)
                    {
                        if (a.cantidadUso == 0)
                        {
                            //para los casos de  registros basura
                            //si cambio el proveedor en el comparativo
                            _db.ComparativoItemSelecPrv.DeleteOnSubmit(a);
                        }
                    }
                    //-----------
                    _db.SubmitChanges();

                    var cpi = from a in _db.ComparativoItemSelecPrv
                              where a.idComparativoProv == comparativoProveedor.idinternal &
                              a.idComparativoItem == i.idInternal
                              select a;



                    // si ya existio un registro entonces lo actualizo
                    if (cpi.Count() > 0)
                    {
                        ComparativoItemSelecPrv cisp = cpi.First();
                        //mas lo disponible
                        cisp.cantidad = cisp.cantidadUso + (i.cantidadBase - i.cantUso);
                        //cisp.precio = i.precio1;
                        cisp.total = cisp.cantidad * cisp.precio;
                        
                        //cisp.cantidadUso = 0;
                        //cisp.totalUso = 0;
                        //  _db.ComparativoItemSelecPrv.InsertOnSubmit(cisp);


                    }
                    else
                    {
                        if (comparativoProveedor.item == 1)
                        {
                            ComparativoItemSelecPrv cisp = new ComparativoItemSelecPrv();
                            //siempre con la cantidad  disponible
                            decimal cantidad = i.cantidadBase.Value - i.cantUso.Value;
                            decimal total = cantidad * i.precio1.Value;

                            cisp.AddCItemSelecProv(_db,
                                i.idInternal,
                                comparativoProveedor.idinternal,
                                cantidad,
                                i.precio1.Value,
                                total);

                        }

                        if (comparativoProveedor.item == 2)
                        {
                            ComparativoItemSelecPrv cisp = new ComparativoItemSelecPrv();
                            //siempre con la cantidad  disponible
                            decimal cantidad = i.cantidadBase.Value - i.cantUso.Value;
                            decimal total = cantidad * i.precio2.Value;

                            cisp.AddCItemSelecProv(_db,
                                i.idInternal,
                                comparativoProveedor.idinternal,
                                cantidad,
                                i.precio2.Value,
                                total);


                        }
                        if (comparativoProveedor.item == 3)
                        {

                            ComparativoItemSelecPrv cisp = new ComparativoItemSelecPrv();
                            //siempre con la cantidad  disponible
                            decimal cantidad = i.cantidadBase.Value - i.cantUso.Value;
                            decimal total = cantidad * i.precio3.Value;

                            cisp.AddCItemSelecProv(_db,
                                i.idInternal,
                                comparativoProveedor.idinternal,
                                cantidad,
                                i.precio3.Value,
                                total);

                        }


                    }
                    _db.SubmitChanges();

                }
                // al final para verifar que no debe de quedar en negativo
                //si el que actualizo es el mismo comparativo que  utiliceen la orden de compra si permitir


                //verificarSaldos(_db, idComparativo);
                comparativoProveedor.updateTotalContratoAll(_db, idComparativo);
                // actualiza el proveedor
                
                _db.SubmitChanges();
                result = true;
                ts.Complete();

                return result;
            }
        }


       //public bool updateAprobacion(int idComparativo)
       // {
       //     bool result = false;
       //     dbGestionDataContext _db =
       //         new dbGestionDataContext(Parametros.strConnString);


       //     ComparativoProveedor cp = new ComparativoProveedor();

       //     //obteniendo variables de session
       //      int idEmpleadoAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

         

       //     var q = from a in _db.ComparativoProveedors
       //             where a.idComparativo == idComparativo & a.bitSeleccion == true
       //             select a;
       //     if (q.Count() == 0)
       //     {
       //         throw new Exception("Debe seleccionar un proveedor");
       //     }

       //     ComparativoProveedor cpom = q.First();
       //     Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);

       //     var we = from a in _db.EmpleadoObra
       //              where a.idEmpleado == idEmpleadoAprob & 
       //              a.idObra == comparativo.idObra
       //              select a;

       //     if (we.Count() == 0)
       //     {
       //         throw new Exception("No tiene permisos en Obra");
       //     }

       //     //buscamos que tenga un nivel de aprobacion
       //     Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

       //     if (rolEmpleado.nivelComparativo == 0)
       //     {
       //         throw new Exception("No tiene acceso Aprobar Comparativo");
       //     }
       //     if (rolEmpleado.nivelComparativo == 1)
       //     {
       //         if (comparativo.idEstado == 3)
       //         {
       //             throw new Exception("El Comparativo ya se encuentra Aprobado ");
       //         }
       //         comparativo.UpdateRevisor(_db, idEmpleadoAprob);
       //         result = true;
       //     }


       //     if (rolEmpleado.nivelComparativo >= 2)
       //     {
                

       //         if (comparativo.idEstado == 14)
       //         {
       //             throw new Exception("El Comparativo se encuentra Finalizado");
       //         }
       //         if (comparativo.idEstado == 3)
       //         {
       //             throw new Exception("El Comparativo ya se encuentra Aprobado ");
       //         }

       //         //aqui para  la aprobacion segun monto

       //         if (Math.Round(cpom.totalContratado.Value * cpom.tipoCambio.Value,0) > Math.Round(rolEmpleado.montoComparativo.Value,0) & rolEmpleado.montoComparativo != -1)
       //         {
       //             if (rolEmpleado.nivelComparativo==2)
       //             {
       //             string mensage = String.Format("No puede aprobar Montos Superiors a {0:N}", rolEmpleado.montoComparativo.Value);
       //             throw new Exception(mensage);
       //             }
                  
       //         }

       //         // para las  aprobacion con otro  nivel de aporbacion  3
               
       //         if (Math.Round(cpom.totalContratado.Value * cpom.tipoCambio.Value,0)> Math.Round(comparativo.totalBase.Value,0))
       //         {
       //             if (rolEmpleado.nivelComparativo == 2)
       //             {
       //                 throw new Exception("Monto a Contratar es mayor a MontoBase del Comparativo,Necesita aprobacion 3");
       //             }
       //             if (rolEmpleado.nivelComparativo == 1)
       //             {
                       
       //             }
       //         }

       //         EstructuraCosto EC = _db.EstructuraCostos.Single(p => p.idInternal == comparativo.idEstructuraCosto);

       //         if (comparativo.idEmpleadoRevisor == null)
       //         {
       //             comparativo.UpdateRevisor(_db, idEmpleadoAprob);
       //         }
       //         comparativo.UpdateAprobacion(_db, idEmpleadoAprob);

       //         EC.updateControlitem(_db, idComparativo);
       //         EC.updateUsoFromComparativo(_db);
       //         //al final para verificar que no debe existe  difeferencias 
           
       //         result = true;
       //     }
           
       //     return result;

       // }



        public bool updateAprobacionNivel1(int idComparativo)
        {
            bool result = false;
            dbGestionDataContext _db =
                new dbGestionDataContext(Parametros.strConnString);


            ComparativoProveedor cp = new ComparativoProveedor();

            //obteniendo variables de session
            int idEmpleadoAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());



            var q = from a in _db.ComparativoProveedors
                    where a.idComparativo == idComparativo & a.bitSeleccion == true
                    select a;
            if (q.Count() == 0)
            {
                throw new Exception("Debe seleccionar un proveedor");
            }

            ComparativoProveedor cpom = q.First();
            Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);

            var we = from a in _db.EmpleadoObras
                     where a.idEmpleado == idEmpleadoAprob &
                     a.idObra == comparativo.idObra
                     select a;

            if (we.Count() == 0)
            {
                throw new Exception("No tiene permisos en Obra");
            }

            //buscamos que tenga un nivel de aprobacion
            Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

            if (rolEmpleado.nivelComparativo == 0)
            {
                throw new Exception("No tiene acceso Aprobar Comparativo");
            }
            if (rolEmpleado.nivelComparativo >= 1)
            {
                if (comparativo.idEstado == 3)
                {
                    throw new Exception("El Comparativo ya se encuentra Aprobado ");
                }
                if (comparativo.idEmpleadoRevisor == null)
                {
                    comparativo.UpdateRevisor(_db, idEmpleadoAprob);
                    
                }
                result = true;
            }


           

            return result;

        }


        public bool updateAprobacionNivel2(int idComparativo)
        {
            bool result = false;
            dbGestionDataContext _db =
                new dbGestionDataContext(Parametros.strConnString);


            //ComparativoProveedor cp = new ComparativoProveedor();

            //obteniendo variables de session
            int idEmpleadoAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());



            var q = from a in _db.ComparativoProveedors
                    where a.idComparativo == idComparativo & a.bitSeleccion == true
                    select a;
            if (q.Count() == 0)
            {
                throw new Exception("Debe seleccionar un proveedor");
            }

            ComparativoProveedor cpom = q.First();
            Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);

            var we = from a in _db.EmpleadoObras
                     where a.idEmpleado == idEmpleadoAprob &
                     a.idObra == comparativo.idObra
                     select a;

            if (we.Count() == 0)
            {
                throw new Exception("No tiene permisos en Obra");
            }

            //buscamos que tenga un nivel de aprobacion
            Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

            if (rolEmpleado.nivelComparativo ==0)
            {
                throw new Exception("No tiene acceso Aprobar  Comparativo ");
            }
            if (rolEmpleado.nivelComparativo >= 2)
            {


                if (comparativo.idEstado == 14)
                {
                    throw new Exception("El Comparativo se encuentra Finalizado");
                }
                if (comparativo.idEstado == 3)
                {
                    throw new Exception("El Comparativo ya se encuentra Aprobado ");
                }

                decimal montoEvaluar=Math.Round(cpom.totalContratado.Value * cpom.tipoCambio.Value, 0);   //convertido en soles
                decimal montoCOMP = Math.Round(cpom.totalContratado.Value, 0);
                decimal montoEC = Math.Round(comparativo.totalComparativo.Value, 0);
                
                validaAprobacion2(rolEmpleado,montoEvaluar);
                validaAprobacion3(rolEmpleado, montoEC, montoCOMP);
               

                if (comparativo.idEmpleadoRevisor == null)
                {
                    comparativo.UpdateRevisor(_db, idEmpleadoAprob);
                }

                comparativo.UpdateAprobacion(_db, idEmpleadoAprob);
                EstructuraCosto EC = _db.EstructuraCostos.Single(p => p.idInternal == comparativo.idEstructuraCosto);
               

                //EC.updateControlitem(_db, idComparativo); ya no debe validar los recursos
                EC.updateUsoFromComparativo(_db);
                //al final para verificar que no debe existe  diferencias 

                result = true;
            }

            return result;

        }

        public void validaAprobacion2(Rol rolEmpleado,decimal  montoEvaluar)
        {
            //aqui para  la aprobacion segun monto

            if (montoEvaluar > Math.Round(rolEmpleado.montoComparativo.Value, 0) & rolEmpleado.montoComparativo != -1)
            {
                if (rolEmpleado.nivelComparativo == 2)
                {
                    string mensage = String.Format("No puede aprobar Montos Superiors a {0:N}", rolEmpleado.montoComparativo.Value);
                    throw new Exception(mensage);
                }

            }

          

        }

        public void validaAprobacion3(Rol rolEmpleado, decimal montoDisp,decimal montoCompra)
        {
            // para las  aprobacion con otro  nivel de aporbacion  3

            if (montoCompra > montoDisp)
            {                                   
                if (rolEmpleado.nivelComparativo != 3)
                {
                    throw new Exception("Monto a Contratar es mayor al MontoBase, Necesita aprobacion 3");
                }
                
            }

        }

        public void verificarSaldos(dbGestionDataContext _db, int idComparativo)
        {
            //si fueron cambiados desde la ultima vez
            //para aquellos recursos libres en monto /sin uso dela orden de compra

            var w = from a in _db.ComparativoItems
                    where a.idComparativo == idComparativo &
                    a.ComparativoItemSelecPrvs.Sum(p=>p.cantidad) > a.ComparativoItemSelecPrvs.Sum(p=>p.cantidadUso) 
                    select a;
           
            foreach (var itemComparativo in w)
            {

                // para comparar necesito el tipo de cambio  de la estructura
                EstructuraCostoItem ecitem = _db.EstructuraCostoItems.Single(p => p.idInternal == itemComparativo.idEstructuraCostoItem);

                decimal totalOrigen= itemComparativo.totalBaseOrigen.Value-itemComparativo.ComparativoItemSelecPrvs.Sum(p=>p.totalUso).Value;
                decimal totalitemComparativoSoles = (totalOrigen * itemComparativo.tipoCambio.Value);
                // restamos lo ya utilizado en las ordenes de compra para el caso que este es el mismo comprativo 
              

                decimal totalitemECostoItemSoles = (ecitem.total.Value - ecitem.totalUso.Value) * ecitem.tipoCambio.Value;
                // la comparacion lo realizo en soles
                //totalBaseOrig=totalDisp  por vista se cambio en nombre

                if (Math.Round(totalitemComparativoSoles, 2) > Math.Round(totalitemECostoItemSoles, 2))
                {
                    throw new Exception("Existe diferencia con los saldos actuales, vuelva a generar otro Comparativo :" + itemComparativo.descripcion);
                }
            }
        }
    /// <summary>
    /// Desaprobar comparativo , solo si no exista Ordenes de Compra, Debe Estar Aprobado1 y Aprobacion2
    /// el usuario tene que tener  nivel de aprobacion 2 en el rol
    /// </summary>
    /// <param name="idComparativo"></param>
    /// <returns></returns>
        public bool updateDesAprobacion(int idComparativo)
        {
            bool result = false;
            //


            using (TransactionScope ts = new TransactionScope())
            {


                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                int idEmpleadoDesAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);
                List<int> items = _db.ComparativoItems.Where(p => p.idComparativo == idComparativo).Select(p => p.idInternal).ToList();
                ComparativoProveedor comparativoProveedor = _db.ComparativoProveedors.Single(p => p.bitSeleccion == true & p.idComparativo == idComparativo);

                //var q = from a in _db.OrdenCompras
                //        where a.idComparativo == idComparativo
                //        select a;

                //if (q.Count()>0)
                //{
                //    throw new Exception("Existe Ordenes de Compra Registradas.Para desaprobar Comparativos no debe existir Orden de Compra incluyendo los anulados ");

                //}

                //validad nodo la transaccion
                // 3 aprobacon 2
                if (comparativo.idEstado == 1)
                {
                    throw new Exception("El comparativo no puede ser DesAprobado");
                }
                //borramos el autorizado y Revisado

                //////////------------------------------------------///////////////////////

                var we = from a in _db.EmpleadoObras
                         where a.idEmpleado == idEmpleadoDesAprob & a.Rol.nivelComparativo != 0 &
                         a.idObra == comparativo.idObra
                         select a;

                if (we.Count() == 0)
                {
                    throw new Exception("No tiene permisos en Obra");
                }

                //buscamos que tenga un nivel de aprobacion
                Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

                if (rolEmpleado.nivelComparativo == 0)
                {
                    throw new Exception("No tiene acceso Desaprobar Comparativo");
                }

                if (rolEmpleado.nivelComparativo == 1 & comparativo.idEstado == 3)
                {
                    // el usuario no debe de desaprobar 

                    throw new Exception("No tiene nivel para desaprobar el comparativo");
                }

                if (rolEmpleado.nivelComparativo == 1 & comparativo.idEstado == 2)
                {
                   //solo puede si el estado es aprobacion 1

                   
                    comparativo.updateDesAprobacion(_db, idEmpleadoDesAprob);
                   // comparativoProveedor.bitSeleccion = false;
                   // _db.SubmitChanges();
                   
                }

                if (rolEmpleado.nivelComparativo >= 2 & comparativo.idEstado == 2)
                {
                    //solo puede si el estado es aprobacion 2
                    comparativo.updateDesAprobacion(_db, idEmpleadoDesAprob);
                    //comparativoProveedor.bitSeleccion = false;
                   // _db.SubmitChanges();
                 

                }
                if (rolEmpleado.nivelComparativo >= 2 & (comparativo.idEstado == 3 | comparativo.idEstado == 2))
                {
                    //3 desaprobado
                    comparativo.updateDesAprobacion(_db, idEmpleadoDesAprob);
                    //comparativoProveedor.bitSeleccion = false;
                   // _db.SubmitChanges();
                    
                   EstructuraCosto EC = _db.EstructuraCostos.Single(p => p.idInternal == comparativo.idEstructuraCosto);

                   
                    EC.updateUsoFromComparativo(_db);
                    
                }



                    ts.Complete();
                    result = true;


                /////////////------------------------------------///////////////////////////////
               



            }
            return result;
        }


        public bool finalizarContrato(int idComparativo)
        {




            using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
            {

                //obteniendo variables de session
                int idEmpleadoAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);
                List<int> items = (from a in _db.ComparativoItems
                                   where a.idComparativo == idComparativo
                                   select a.idInternal).ToList();

                var we = from a in _db.EmpleadoObras
                         where a.idEmpleado == idEmpleadoAprob &
                         a.idObra == comparativo.idObra
                         select a;

                if (we.Count() == 0)
                {
                    throw new Exception("No tiene permisos en Obra");
                }


                //buscamos que tenga un nivel de aprobacion
                Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

                if (rolEmpleado.nivelComparativo < 2)
                {
                    throw new Exception("No tiene Nivel de Aprobacion para esta operacion en el Comparativo");
                }

                var oc = from a in _db.OrdenCompras
                         where a.idComparativo == idComparativo
                         select a;

                if (oc.Count() == 0)
                {
                    throw new Exception("Debe Existir Ordenes de Compra");
                }
                //solo como referencia para la devolucion;
                using (TransactionScope ts = new TransactionScope())
                {

                    
                    comparativo.idEstado = 14; //devolucion
                    _db.SubmitChanges();
                    CerrarItem(_db,comparativo,9, idEmpleadoAprob, items);
                    ts.Complete();
                }

            }
            return true;
        }

        public bool devolucion(int idComparativo,
                              int idMotivo,
                              List<int> ComparativosItems)
        {
            ///para el caso de  concluir item del comparativo 
            ///regresa a la estructura para poder ser utilizado
            ///
            ///
            if (ComparativosItems.Count==0)
            {
                throw new Exception("No  existe item para devolucion");
            }
            
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {

                    //obteniendo variables de session
                    int idEmpleadoAprob = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());


                    Comparativo comparativo = _db.Comparativos.Single(p => p.idInternal == idComparativo);
                   

                    var we = from a in _db.EmpleadoObras
                             where a.idEmpleado == idEmpleadoAprob &
                             a.idObra == comparativo.idObra
                             select a;

                    if (we.Count() == 0)
                    {
                        throw new Exception("No tiene permisos en Obra");
                    }

                    //buscamos que tenga un nivel de aprobacion
                    Rol rolEmpleado = _db.Rols.Single(p => p.idInternal == we.First().idRol);

                    if (rolEmpleado.nivelComparativo < 2)
                    {
                        throw new Exception("No tiene Nivel de Aprobacion para esta operacion en el Comparativo");
                    }

                    var oc = from a in _db.OrdenCompras
                             where a.idComparativo== idComparativo
                             select a;

                    if (oc.Count() == 0)
                    {
                        throw new Exception("Debe Existir Ordenes de Compra");
                    }
                    //solo como referencia para la devolucion;
                    

                    //los item no deben estar finalizados
                    var bit = from a in _db.ComparativoItems
                              where ComparativosItems.Contains(a.idInternal)
                              & a.bitFinalizado==true
                              select a;
                    if (bit.Count() > 0)
                    {
                        throw new Exception("Los Item No deben estar Finalizados, Verifique");
                    }

                    using (TransactionScope ts = new TransactionScope())
                    {

                        CerrarItem(_db, comparativo, idMotivo, idEmpleadoAprob, ComparativosItems);
                  
                        
                        
                        
                        ts.Complete();
                }
                
            }
            return true;


           
        }

      

        public void CerrarItem(dbGestionDataContext _db,
                                Comparativo comparativo,
                                int idMotivo, 
                                int idEmpleadoAprob,
                                 List<int> ComparativosItems)
        {

            //registranos la transaccion
            //del comparativo para guardar su historico

            ComparativoProveedor comparativoProveedor=
                                            _db.ComparativoProveedors.Single(p => p.idComparativo == comparativo.idInternal
                                                & p.bitSeleccion == true);

            EstructuraCosto EC =
                          _db.EstructuraCostos.Single(p => p.idInternal == comparativoProveedor.Comparativo.idEstructuraCosto.Value);
           

            
                            decimal totalBaseAprov = comparativo.totalComparativo.Value;

                            decimal totalAprov = comparativoProveedor.total.Value;


                            var totalBaseItem = (from a in _db.ComparativoItems
                                                 where ComparativosItems.Contains(a.idInternal)
                                                 select a.totalBaseOrigen).Sum();

                            var totalDevolucion = (from a in _db.ComparativoItems
                                                   where ComparativosItems.Contains(a.idInternal)
                                                   select a.totalBaseOrigen - a.ComparativoItemSelecPrvs.Sum(e => e.totalUso.Value)).Sum();



            ComparativoDevolucion cd = new ComparativoDevolucion();
            
                    cd.add(_db,
                        comparativo.idInternal,
                        totalBaseAprov,
                        totalAprov,
                        idMotivo,
                        totalBaseItem.Value,
                        totalDevolucion.Value,
                        idEmpleadoAprob);

                  

            

            List<int> lista = new List<int>();
            // cerramos los valores contratados
            var q = from a in _db.ComparativoItemSelecPrv
                   
                    where a.idComparativoProv == comparativoProveedor.idinternal
                    & ComparativosItems.Contains(a.idComparativoItem.Value)
                    select a;

            foreach (var a in q)
            {
                a.total = a.totalUso;
                a.cantidad = a.cantidadUso;
                a.ComparativoItem.bitFinalizado = true;

                if (a.ComparativoItem.totalBaseOrigen > a.totalUso)
                {
                    
                        // para el caso donde  exista montos por devolver
                            //if (idMotivo != 9)
                            //    {
                            //        throw new Exception("No se puede  Devolver  Recurso:{0}-{1} verifique".Fmt(a.ComparativoItem.codigo, a.ComparativoItem.descripcion));
                            //    }
                            ComparativoDevItem dev = new ComparativoDevItem();
                            dev.Add(_db,
                                cd.idInternal,
                                a.ComparativoItem.idInternal,
                                a.ComparativoItem.totalBaseOrigen.Value,
                                a.ComparativoItem.totalCantidadOrig.Value,
                                a.totalUso.Value,
                                a.cantidadUso.Value);
                
                            //resta del origen base
                            a.ComparativoItem.totalBaseOrigen = a.totalUso;
                            a.ComparativoItem.totalCantidadOrig = a.cantidadUso;
                              a.ComparativoItem.cantidadBase = a.cantidad;                    
                                //recalcular el ECitem
                                //debe ademas crear una transaccion de agrupacion  para controlar las devoluciones
                                // creamos un ECItem por la difrencia
                                //verificamos que no se repita mas de una vez el recurso
                                if (!lista.Exists(p=>p==a.ComparativoItem.idEstructuraCostoItem.Value))
                                {
                                     //para el caso de cambio desde el comparativo los item de la EC se crearan  si existe diferencias
                           
                                     a.ComparativoItem.EstructuraCostoItem.updateBaseFromComparativo(_db, idEmpleadoAprob,a.idComparativoItem.Value);
                                    lista.Add(a.ComparativoItem.idEstructuraCostoItem.Value);
                                }   
            
                                if (comparativoProveedor.item == 1) { a.ComparativoItem.total1 = a.totalUso; }
                                if (comparativoProveedor.item == 2) { a.ComparativoItem.total2 = a.totalUso; }
                                if (comparativoProveedor.item == 3) { a.ComparativoItem.total3 = a.totalUso; }

                }

                }

                _db.SubmitChanges();
                // conservar el proveedor
                // actualizamos los valores a tomar en la transacciones de la E/C
                comparativo.updateTotalComparativo(_db);
                comparativoProveedor.updateTotalContratoAll(_db, comparativoProveedor.idComparativo.Value);
                EC.updateUsoFromComparativo(_db);
                
            
          
            
        }






        public void DeleteCerrarItem(dbGestionDataContext _db,
                                    int idComparativoDevolucion)
        {

            //registranos la transaccion
            //del comparativo para guardar su historico

            using (TransactionScope ts = new TransactionScope())
            {

                ComparativoDevolucion comparativoDevolucion = _db.ComparativoDevolucions.Single(p => p.idInternal == idComparativoDevolucion);

                //recuperamos los comparativositem para su update
                List<int> item = comparativoDevolucion.ComparativoDevItems.Select(p => p.idComparativoItem).ToList();


                _db.ComparativoDevolucions.DeleteOnSubmit(comparativoDevolucion);
                _db.ComparativoDevItems.DeleteAllOnSubmit(comparativoDevolucion.ComparativoDevItems);
                _db.SubmitChanges();

                var comparativoItemList = from a in _db.ComparativoItems
                                          where item.Contains(a.idInternal)
                                          select a;

                //eliminamos los EcItemcreados

                foreach (var comparativoitem in comparativoItemList)
                {
                    //traemos el que fue creado por devolucion
                    EstructuraCostoItem ecitem = _db.EstructuraCostoItems.Single(p => p.ComparativoItemRef == comparativoitem.idInternal);

                    if (ecitem.totalUso > 0)
                    {
                        throw new Exception("El recurso generado en la estructura :{0} se encuentra utilizado".Fmt(comparativoitem.EstructuraCostoItem.descripcion));
                    }

                    // necesito estos montos y cantidades adicionar al comparativoItem origen  y comparativoItemSelect

                    comparativoitem.bitFinalizado = false;

                    //actualizamos el ECitem origen
                    comparativoitem.EstructuraCostoItem.total = comparativoitem.EstructuraCostoItem.total + ecitem.total;
                    //si es global sigue siendo 1
                    comparativoitem.EstructuraCostoItem.cantidad = comparativoitem.EstructuraCostoItem.cantidad + ecitem.cantidad;

                    //debido a que el item usado en el comparativo refleja el real utilizado solo es necesario actualizar
                    //la estructuracostoItem , mas no el comparativo item.

                    _db.EstructuraCostoItems.DeleteOnSubmit(ecitem);
                    _db.SubmitChanges();
                }
                ts.Complete();
            }
        }


        //public bool addContratoDirectoProveedor(int idComparativo,
        //                                        int idproveedor,
        //                                        int idMoneda,
        //                                        int idFormaPago,
        //                                        string condicion,
        //                                        List<view_comparativoItemAddProv> cpItem)
        //{

        //    using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
        //    {
        //        decimal tipoCambio;
        //        decimal total;
        //        ComparativoProveedor cp = new ComparativoProveedor();
        //        cp.addProveedor(_db,
        //            idComparativo,
        //            idproveedor,
        //            4,
        //            condicion,
        //            0,
        //            idMoneda,
        //            idFormaPago,
        //            0);

        //        //Registamos  primero los valores de  los nuevos item

        //        // contrato directo
        //        foreach (var a in cpItem)
        //        {
        //            ComparativoItemSelecPrv comparativoItem = new ComparativoItemSelecPrv();
        //            comparativoItem.AddCItemSelecProv(
        //                _db,
        //                a.idInternal,
        //                cp.idinternal,
        //                a.cantidad.Value,
        //                a.precio,
        //                a.total);

        //            ComparativoItem b = _db.ComparativoItems.Single(p => p.idInternal == a.idInternal);
        //            b.updateTotalesUso(_db);

        //        }
        //        // actualizamos los item de contrato directo

        //    }

        //    return true;
        //}
        public bool deleteContratoDirectoProveedor(int idComparativo)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                using (dbGestionDataContext _db = new dbGestionDataContext(Parametros.strConnString))
                {
                    //verificamos la existencia del 4 proveedor el cual es contrato directo

                    var q = from a in _db.ComparativoProveedors
                            where a.idComparativo == idComparativo & a.item == 4
                            select a;


                    if (q.Count() == 0)
                    {
                        throw new Exception("No existe proveedor de contrato Directo");
                    }

                    // verificamos que no se encuentre utilizado
                    ComparativoProveedor cp = q.First();
                    if (cp.totalUso > 0)
                    {
                        throw new Exception("Existe Ordenes de Compra  registradas");
                    }

                    //eliminamos los item de comparativoSeleccion Proveedor

                    var item = from a in _db.ComparativoItemSelecPrv
                               where a.idComparativoProv == cp.idinternal
                               select a;

                    _db.ComparativoItemSelecPrv.DeleteAllOnSubmit(item);
                    _db.SubmitChanges();

                    //update sus padres
                    var comparativoitem = from b in _db.ComparativoItems
                                          where b.idComparativo == idComparativo & b.bitSel == true
                                          select b;

                    foreach (var i in comparativoitem)
                    {
                        i.updateTotalesUso(_db);
                    }

                    //Eliminamos el item 4
                    _db.ComparativoProveedors.DeleteOnSubmit(cp);
                    _db.SubmitChanges();
                    ts.Complete();
                    return true;
                }
            }



        }




        private IQueryable<ComparativoListInfo> ApplySelect_ComparativoListInfo()
        {


            var q= from a in DbUtil.Db.Comparativos
                   select new ComparativoListInfo
                    {
                        idInternal = a.idInternal,
                        idObra = a.idObra.Value,
                        idEstructuraCosto = a.idEstructuraCosto.Value,
                        fecha = a.fecha.Value,
                        fechaStr = a.fecha.Value.ToShortDateString(),
                        numDocumento = a.numDocumento,
                        estructura = a.EstructuraCosto.Estructura.descripcion,
                        descripcion = a.descripcion,
                        
                        totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalComparativo.Value),
                        totalBaseProveedorSelecMon = 
                        string.Format("{0} {1:N}", a.Moneda.simbol, a.getMontoBaseContrataListaTotal(DbUtil.Db)),
                        totalContratadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado).Value),
                        totalPorAprobarMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado.Value - p.totalUso.Value)),
                        tipoCambio=a.tipoCambio,

                        totalBase = a.totalComparativo.Value,
                        totalBaseProveedorSelec = a.getMontoBaseContrataListaTotal(DbUtil.Db),
                        totalContratado = a.ComparativoProveedors.Sum(p => p.totalContratado).Value,
                        totalPorAprobar =  a.ComparativoProveedors.Sum(p => p.totalContratado.Value - p.totalUso.Value),
                        
                        idEstado=a.idEstado.Value,
                        
                        estado = (a.idEstado==1& a.idProveedorSelec!=null)?"Pendiente":a.GrupoDatoitem.descripcion,
                        proveedorSelec = a.Proveedor.descripcion,
                        fechaAprob = a.fechaAprob,
                        fechaAprobStr = (a.fechaAprob == null) ? "" : a.fechaAprob.Value.ToShortDateString(),
                       // Imprimir=(a.idProveedorSelec==null)?"":"imprimir",

                        codDescripcionEC = a.EstructuraCosto.idInternal.ToString() + " - " + a.EstructuraCosto.descripcion
                    };


            return q;
        }

     [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<ComparativoListInfo> getComparativoList(int idEstructuraCosto, int idObra, int startRowIndex, int maximumRows, string sortExpression)
        {

            var q = ApplySelect_ComparativoListInfo();
            q = q.Where(a => a.idEstructuraCosto == idEstructuraCosto
                & a.idObra==idObra);
            _count = q.Count();


            q = ApplySort(q, sortExpression);
            return q.Skip(startRowIndex).Take(maximumRows).ToList();
        }



     [DataObjectMethod(DataObjectMethodType.Select, false)]
     public IEnumerable<ComparativoListInfo> getComparativoList(int idObra, DateTime? fechaInicio, DateTime? fechaFin, int startRowIndex, int maximumRows, string sortExpression)
     {
        var q = ApplySelect_ComparativoListInfo();
         q = q.Where(a =>a.idObra == idObra & a.fecha > fechaInicio & a.fecha < fechaFin.Value.AddDays(1));
         _count = q.Count();

        q = ApplySort(q, sortExpression);
        return q.Skip(startRowIndex).Take(maximumRows).ToList();
     }
    


     [DataObjectMethod(DataObjectMethodType.Select, false)]
     public IEnumerable<ComparativoListInfo> getComparativoFiltroList(int idObra,
         string codigoStr,
         string descripcionStr,
         string estadoStr,
         string proveedorStr, 
         DateTime? fechaInicio, 
         DateTime? fechaFin, 
         int startRowIndex, 
         int maximumRows, 
         string sortExpression)
     {
         if (!proveedorStr.HasValue())
             proveedorStr = "";
         if (!codigoStr.HasValue())
             codigoStr = "";
         if (!descripcionStr.HasValue())
             descripcionStr = "";

         var q = ApplySelect_ComparativoListInfo();

         if (estadoStr == "0") //todos
         {
             q = q.Where(a => a.idObra == idObra &
             a.fecha > fechaInicio &
             a.fecha < fechaFin.Value.AddDays(1)
             & a.proveedorSelec.Contains(proveedorStr)
             & a.descripcion.Contains(descripcionStr)
             & a.numDocumento.Contains(codigoStr)
             );
         }
         if (estadoStr == "20") //pendientes
         {
             q = q.Where(a => a.idObra == idObra &
              a.fecha > fechaInicio &
              a.fecha < fechaFin.Value.AddDays(1)
              & a.proveedorSelec.Contains(proveedorStr)
              & (a.idEstado==1 |a.idEstado==2)
              & a.descripcion.Contains(descripcionStr)
             & a.numDocumento.Contains(codigoStr)
              );
         }
         if (estadoStr != "20" & estadoStr !="0") //pendientes
         {
             q = q.Where(a => a.idObra == idObra &
                 a.fecha > fechaInicio &
                 a.fecha < fechaFin.Value.AddDays(1)
                 & a.proveedorSelec.Contains(proveedorStr)
                 & a.idEstado ==Convert.ToInt32(estadoStr)
                 & a.descripcion.Contains(descripcionStr)
                 & a.numDocumento.Contains(codigoStr)
                 );
         }
         
         
         _count = q.Count();

         q = ApplySort(q, sortExpression);
         return q.Skip(startRowIndex).Take(maximumRows).ToList();
     }

    
        #region "get Comparativo control"


        int _count;

        public int Countc(int startRowIndex, int maximumRows, string sortExpression,int idComparativo)
        {
            return _count;
        }

    
        public int Count( int startRowIndex, int maximumRows, string sortExpression,int idObra)
        {
            return _count;
        }

        public int Count(int idObra, string descripcionStr,string codigoStr  ,string estadoStr, string proveedorStr, DateTime? fechaInicio, DateTime? fechaFin, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }


        

        public int Count(int idObra, DateTime? fechaInicio, DateTime? fechaFin, int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }
        public int Count(int startRowIndex, int maximumRows, string sortExpression)
        {
            return _count;
        }
        public int Count(int startRowIndex, int idEstructuraCosto,int idObra, int maximumRows, string sortExpression)
        {
            return _count;
        }
        private IQueryable<ComparativoPendienteInfo> ApplySort(IQueryable<ComparativoPendienteInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "fecha":
                    q = q.OrderBy(b => b.fecha);
                    break;
                case "fecha DESC":
                    q = q.OrderByDescending(b => b.fecha);
                    break;
                case "Descripcion":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "Descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;
                case "numDocumento":
                    q = q.OrderBy(b => b.numDocumento);
                    break;
                case "numDocumento DESC":
                    q = q.OrderByDescending(b => b.numDocumento);
                    break;
                case "proveedor":
                    q = q.OrderBy(b => b.proveedor);
                    break;
                case "proveedor DESC":
                    q = q.OrderByDescending(b => b.proveedor);
                    break;

                case "totalComparativo":
                    q = q.OrderBy(b => b.totalComparativo);
                    break;
                case "totalComparativo DESC":
                    q = q.OrderByDescending(b => b.totalComparativo);
                    break;

                case "totalXContratar":
                    q = q.OrderBy(b => b.totalXContratar);
                    break;
                case "totalXContratar DESC":
                    q = q.OrderByDescending(b => b.totalXContratar);
                    break;
                case "estado":
                    q = q.OrderBy(b => b.estado);
                    break;
                case "estado DESC":
                    q = q.OrderByDescending(b => b.estado);
                    break;
                case "Obra":
                    q = q.OrderBy(b => b.Obra);
                    break;
                case "Obra DESC":
                    q = q.OrderByDescending(b => b.Obra);
                    break;
                default:
                    q = q.OrderByDescending(b => b.fecha);
                    break;

            }
            return q;
        }

        private IQueryable<ComparativoListInfo> ApplySort(IQueryable<ComparativoListInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "fecha":
                    q = q.OrderBy(p=>p.numDocumento).OrderBy(b => b.fecha);
                    break;
                case "fecha DESC":
                    q = q.OrderByDescending(p => p.numDocumento).OrderByDescending(b => b.fecha);
                    break;
                case "descripcion":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;
                case "numDocumento":
                    q = q.OrderBy(b => b.numDocumento);
                    break;
                case "numDocumento DESC":
                    q = q.OrderByDescending(b => b.numDocumento);
                    break;
               

                case "codDescripcionEC":
                    q = q.OrderBy(b => b.codDescripcionEC);
                    break;
                case "codDescripcionEC DESC":
                    q = q.OrderByDescending(b => b.codDescripcionEC);
                    break;


                case "totalBase":
                    q = q.OrderBy(b => b.totalBase);
                    break;
                case "totalBase DESC":
                    q = q.OrderByDescending(b => b.totalBase);
                    break;
                case "totalBaseProveedorSelec":
                    q = q.OrderBy(b => b.totalBaseProveedorSelec);
                    break;
                case "totalBaseProveedorSelec DESC":
                    q = q.OrderByDescending(b => b.totalBaseProveedorSelec);
                    break;

                

                case "totalContratado":
                    q = q.OrderBy(b => b.totalContratado);
                    break;
                case "totalContratado DESC":
                    q = q.OrderByDescending(b => b.totalContratado);
                    break;


                case "totalPorAprobar":
                    q = q.OrderBy(b => b.totalPorAprobar);
                    break;
                case "totalPorAprobar DESC":
                    q = q.OrderByDescending(b => b.totalPorAprobar);
                    break;

                default:
                    q = q.OrderByDescending(p=>p.numDocumento).OrderByDescending(b => b.fecha);
                    break;

            }
            return q;
        }


        private IQueryable<ComparativoDevItemInfo> ApplySortG(IQueryable<ComparativoDevItemInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "Codigo ASC":
                    q = q.OrderBy(b => b.Codigo);
                    break;
                case "Codigo DESC":
                    q = q.OrderByDescending(b => b.Codigo);
                    break;
                case "descripcion ASC":
                    q = q.OrderBy(b => b.descripcion);
                    break;
                case "descripcion DESC":
                    q = q.OrderByDescending(b => b.descripcion);
                    break;
                case "disponible ASC":
                    q = q.OrderBy(b => b.disponible);
                    break;
                case "disponible DESC":
                    q = q.OrderByDescending(b => b.disponible);
                    break;

                case "unidad ASC":
                    q = q.OrderBy(b => b.unidad);
                    break;
                case "unidad DESC":
                    q = q.OrderByDescending(b => b.unidad);
                    break;


                case "totalContratado ASC":
                    q = q.OrderBy(b => b.totalContratado);
                    break;
                case "totalContratado DESC":
                    q = q.OrderByDescending(b => b.totalContratado);
                    break;

                case "totalOC ASC":
                    q = q.OrderBy(b => b.totalOC);
                    break;
                case "totalOC DESC":
                    q = q.OrderByDescending(b => b.totalOC);
                    break;
                
                default:
                    q = q.OrderBy(b => b.idInternal).OrderByDescending(p => p.Codigo);
                    break;
            }
            return q;
        }

        private IQueryable<ComparativoDevolucionInfo> ApplySort(IQueryable<ComparativoDevolucionInfo> q, string sortExpression)
        {
            switch (sortExpression)
            {
                case "fecha":
                    q = q.OrderBy(b => b.fecha);
                    break;
                case "fecha DESC":
                    q = q.OrderByDescending(b => b.fecha);
                    break;
                case "motivoStr":
                    q = q.OrderBy(b => b.motivoStr);
                    break;
                case "motivoStr DESC":
                    q = q.OrderByDescending(b => b.motivoStr);
                    break;
                case "totalAprov":
                    q = q.OrderBy(b => b.totalAprov);
                    break;
                case "totalAprov DESC":
                    q = q.OrderByDescending(b => b.totalAprov);
                    break;

                case "totalBaseAprov":
                    q = q.OrderBy(b => b.totalBaseAprov);
                    break;
                case "totalBaseAprov DESC":
                    q = q.OrderByDescending(b => b.totalBaseAprov);
                    break;


                default:
                    q = q.OrderBy(b => b.idInternal).OrderByDescending(p => p.fecha);
                    break;
            }
            return q;
        }


        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public List<ComparativoListInfo> getComparativoList(int idObra, DateTime? fechaInicio, DateTime? fechaFin)
        //{

        //    return (from a in DbUtil.Db.Comparativos
        //            where a.idObra == idObra & a.fechacre > fechaInicio & a.fechacre < fechaFin.Value.AddDays(1)
        //            orderby a.numDocumento
        //            select new ComparativoListInfo
        //            {
        //                idInternal = a.idInternal,
        //                idObra = a.idObra.Value,
        //                idEstructuraCosto = a.idEstructuraCosto.Value,
        //                fecha = a.fecha.Value,
        //                numDocumento = a.numDocumento,
        //                estructura = a.EstructuraCosto.Estructura.descripcion,
        //                descripcion = a.descripcion,
        //                totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
        //                totalBaseContradadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.getMontoBaseContrataListaTotal(DbUtil.Db)),
        //                totalContratadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado).Value),
        //                totalPorAprobarMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado.Value - p.totalUso.Value)),
        //                estado = a.getEstadoRpt(a.idEstado.Value, a.GrupoDatoitem.descripcion, a.idProveedorSelec),
        //                proveedorSelec = a.Proveedor.descripcion,
        //                fechaAprob = a.fechaAprob,
        //                codDescripcionEC = a.EstructuraCosto.idInternal.ToString() + " - " + a.EstructuraCosto.descripcion
        //            }).ToList();


        //}



        //[DataObjectMethod(DataObjectMethodType.Select, false)]
        //public List<ComparativoListInfo> getComparativoList(int idObra, DateTime? fechaInicio, DateTime? fechaFin)
        //{

        //    return (from a in DbUtil.Db.Comparativos
        //            where a.idObra == idObra & a.fechacre > fechaInicio & a.fechacre < fechaFin.Value.AddDays(1)
        //            orderby a.numDocumento
        //            select new ComparativoListInfo
        //            {
        //                idInternal = a.idInternal,
        //                idObra = a.idObra.Value,
        //                idEstructuraCosto = a.idEstructuraCosto.Value,
        //                fecha = a.fecha.Value,
        //                numDocumento = a.numDocumento,
        //                estructura = a.EstructuraCosto.Estructura.descripcion,
        //                descripcion = a.descripcion,
        //                totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
        //                totalBaseContradadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.getMontoBaseContrataListaTotal(DbUtil.Db)),
        //                totalContratadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado).Value),
        //                totalPorAprobarMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.ComparativoProveedors.Sum(p => p.totalContratado.Value - p.totalUso.Value)),
        //                estado = a.getEstadoRpt(a.idEstado.Value, a.GrupoDatoitem.descripcion, a.idProveedorSelec),
        //                proveedorSelec = a.Proveedor.descripcion,
        //                fechaAprob = a.fechaAprob,
        //                codDescripcionEC = a.EstructuraCosto.idInternal.ToString() + " - " + a.EstructuraCosto.descripcion
        //            }).ToList();


        //}


       

//        [DataObjectMethod(DataObjectMethodType.Select, false)]
//        public IEnumerable<ComparativoListInfo> getComparativoList(int idObra, DateTime? fechaInicio, DateTime? fechaFin, int startRowIndex, int maximumRows, string sortExpression)
//        {

//                var q= from a in DbUtil.Db.ComparativoProveedors
//                       where a.Comparativo.idObra == idObra & a.Comparativo.fecha > fechaInicio & a.Comparativo.fecha < fechaFin.Value.AddDays(1)
//                       select new ComparativoListInfo
//                       {
//                           idInternal = a.Comparativo.idInternal,
//                           idObra = a.Comparativo.idObra.Value,
//                           idEstructuraCosto = a.Comparativo.idEstructuraCosto.Value,
//                           fecha = a.Comparativo.fecha.Value,
//                           fechaStr = a.Comparativo.fecha.Value.ToShortDateString(),
//                           numDocumento = a.Comparativo.numDocumento,
//                           estructura = a.Comparativo.EstructuraCosto.Estructura.descripcion,
//                           descripcion = a.Comparativo.descripcion,
                           
                           
                           
//                           totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.Comparativo.totalBase.Value), //E/Compras
//                           totalBaseContradadoMon = 
//                           string.Format("{0} {1:N}", a.Moneda.simbol, a.Comparativo.getMontoBaseContrataListaTotal(DbUtil.Db)), //aprobado en el compartivo



////                           totalContratadoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.Comparativo.ComparativoProveedors.Sum(p => p.totalContratado).Value),
                           
////                           totalPorAprobarMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.Comparativo.ComparativoProveedors.Sum(p => p.totalContratado.Value - p.totalUso.Value)),
                           
////totalBaseMon
////totalBaseContradadoMon
////totalUsoOCMon
////totalDevolucionMon
////totalDisponibleMon
                           
//                           estado = a.Comparativo.getEstadoRpt(a.Comparativo.idEstado.Value, a.Comparativo.GrupoDatoitem.descripcion,
//                           a.Comparativo.idProveedorSelec),
//                           proveedorSelec = a.Proveedor.descripcion,
//                           fechaAprob = a.Comparativo.fechaAprob,
//                           fechaAprobStr = (a.fechaAprob2 == null) ? "" : a.fechaAprob2.Value.ToShortDateString(),
//                           codDescripcionEC = a.Comparativo.EstructuraCosto.idInternal.ToString() + " - " + a.Comparativo.EstructuraCosto.descripcion

//                       };
//                      _count = q.Count();
//                        q = ApplySort(q, sortExpression);
//                return q.Skip(startRowIndex).Take(maximumRows);




//        }

        private IQueryable<ComparativoPendienteInfo> GetComparativoPendienteResu()
    {
        

            int? i = (int?)System.Web.HttpContext.Current.Session["idEmpleado"];
            if (i == null)
                return null;

            int idEmpleado = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
            

            var obr = from x in DbUtil.Db.EmpleadoObras
                      where x.idEmpleado == idEmpleado 
                      select new
                      {
                          idInternal = x.Obra.idInternal,
                          descripcion = x.Obra.descripcion,
                          proyecto = x.Obra.Proyecto.descripcion
                      };

            var habiObra = from x in DbUtil.Db.EmpleadoObras
                           where x.idEmpleado == idEmpleado 
                           select x.idObra;




            var q2 = from a in DbUtil.Db.ComparativoProveedors
                     join b in obr on a.Comparativo.idObra equals b.idInternal  into viewObra
                        from c in viewObra.DefaultIfEmpty()
                        where 
                        (a.Comparativo.idEstado == 1 | a.Comparativo.idEstado == 2)
                        & a.bitSeleccion == true
                        & (habiObra.Contains(a.Comparativo.idObra.Value) | a.Comparativo.idObra == null)
                         select new ComparativoPendienteInfo
                         {
                             idInternal = a.Comparativo.idInternal,
                             idObra = a.Comparativo.idObra.Value,
                             fecha = a.Comparativo.fecha.Value,
                             descripcion = a.Comparativo.descripcion,
                             proveedor = a.Comparativo.Proveedor.descripcion,
                             simbol = a.Comparativo.Moneda.simbol,
                             totalComparativo = a.Comparativo.totalComparativo.Value,
                             totalXContratar = a.Comparativo.getMontoContratadoTotal(DbUtil.Db),
                             numDocumento = a.Comparativo.numDocumento,
                             estado = a.Comparativo.GrupoDatoitem.descripcion,
                             Obra = a.Comparativo.Obra.descripcion
                         };
         return q2;
    }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<ComparativoPendienteInfo> getComparativoPendienteResuList(int startRowIndex, 
                                                                                    int maximumRows, 
                                                                                    string sortExpression)
        {



            var q2=this.GetComparativoPendienteResu();
                    

            _count = q2.Count();
            q2 = ApplySort(q2, sortExpression);


            q2 = q2.Skip(startRowIndex).Take(maximumRows);

            return q2;
        }


        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public ComparativoPendienteInfo getComparativoPendienteResuSiguienteList(int idNoConsiderar)
        {

            ComparativoPendienteInfo result =null;
            var q2 = this.GetComparativoPendienteResu();
             q2 = q2.Where(p=>p.idInternal!=idNoConsiderar).OrderBy(p=>p.idObra);

            if (q2.Count() > 0)
            {
                result = q2.First();

            }
            return result;
        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<ComparativoPendienteInfo> getComparativoPendienteList(int idObra, int startRowIndex, int maximumRows, string sortExpression)
        {

           
            var q2 = from a in DbUtil.Db.ComparativoProveedors
                         where a.Comparativo.idObra == idObra &
                         (a.Comparativo.idEstado == 1 | a.Comparativo.idEstado == 2)
                         & a.bitSeleccion == true
                         select new ComparativoPendienteInfo
                         {
                             idInternal = a.Comparativo.idInternal,
                             idObra = a.Comparativo.idObra.Value,
                             fecha=a.Comparativo.fecha.Value,
                             descripcion = a.Comparativo.descripcion,
                             proveedor = a.Comparativo.Proveedor.descripcion,
                             simbol=a.Comparativo.Moneda.simbol,
                             totalComparativo=a.Comparativo.totalComparativo.Value,
                             totalXContratar = a.Comparativo.getMontoContratadoTotal(DbUtil.Db),
                             numDocumento = a.Comparativo.numDocumento,
                             estado = a.Comparativo.GrupoDatoitem.descripcion
                         };

                _count = q2.Count();
                q2 = ApplySort(q2, sortExpression);
               

                q2= q2.Skip(startRowIndex).Take(maximumRows);

                return q2;
        }



#endregion



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<ComparativoItemInfo> getComparativoItemList(int idComparativo)
        {
                var q2 = from a in DbUtil.Db.ComparativoItems
                     where a.bitSel==true
                     & a.idComparativo==idComparativo
                         select new ComparativoItemInfo
                     {
                         
                         bitControlCant=a.bitControlCant.Value, //EC/
                         bitControlCantOrig=a.bitControlCant.Value,
                         bitSel=a.bitSel.Value,
                         cantidadBase=a.cantidadBase.Value,
                         cantidadDisp=a.cantidadBase.Value-a.cantUso.Value,
                         cantidadOrig=a.totalCantidadOrig.Value, //EC
                         cantUso=a.cantUso.Value,
                         codDescripcion=String.Format("{0}-{1}",a.codigo,a.descripcion),
                         codigo=a.EstructuraCostoItem.Insumo.codigo,
                         descripcion = a.EstructuraCostoItem.Insumo.descripcion,
                         idComparativo=a.idComparativo,
                         idEstructuraCostoItem=a.idEstructuraCostoItem.Value,
                         idInternal=a.idInternal,
                         idMonedaBase=a.idMonedaBase.Value,
                         idPadre=a.idPadre,
                         monedaBase=a.Moneda.descripcion,
                         nivel=a.nivel.Value,
                         precio1=a.precio1.Value,
                         precio2=a.precio2.Value,
                         precio3=a.precio3.Value,
                         precioBase=a.precioBase.Value,
                         precioBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.precioBase.Value),
                         simbol1=a.Comparativo.Moneda.simbol,
                         simbolBase=a.Moneda.simbol,
                         tipoCambio=a.tipoCambio.Value,
                         tipoCambioECItem=a.tipoCambioOrig.Value,
                         tipoCambioOrig=a.tipoCambioOrig.Value,
                         total1=a.total1.Value,
                         total2=a.total2.Value,
                         total3=a.total3.Value,
                         totalBase=a.totalBase.Value,
                         totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
                         totalBaseOrigen = a.totalBaseOrigen.Value,
                         totalCantidadOrig = a.totalCantidadOrig.Value,
                         totalDisp=a.totalBase.Value - a.totalUso.Value,
                         totalMonedaBase=a.totalMonedaBase.Value,
                         totalUso=a.totalUso.Value,
                         unidad = a.EstructuraCostoItem.Insumo.InsumoUnidad.abreviacion,

                         totalBaseMonOrig = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBaseOrigen.Value),
                        totalBaseOrig=a.totalBaseOrigen.Value,

                         TotalBaseMonBase=a.totalBase.Value * a.tipoCambio.Value,  //s/.

                         //lo que se trae  desde EstructuraCostoItem actual

                         totalBaseMonOrigen = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBaseOrigen.Value),

                         
                         
                         totalComparar=a.totalBase.Value,
                         totalCompararMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
                         
                         bitFinalizado=a.bitFinalizado.Value,
                         };

                return q2.ToList();


        }

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public IEnumerable<ComparativoItemInfo> getComparativoItemEditList(int idComparativo)
        {
            var q2 = from a in DbUtil.Db.ComparativoItems
                     where a.bitSel == true
                     & a.idComparativo == idComparativo
                     select new ComparativoItemInfo
                     {

                         bitControlCant = a.bitControlCant.Value, //EC/
                         bitControlCantOrig = a.bitControlCant.Value,
                         bitSel = a.bitSel.Value,
                         
                         codDescripcion = String.Format("{0}-{1}", a.codigo, a.descripcion),
                         codigo = a.EstructuraCostoItem.Insumo.codigo,
                         descripcion = a.EstructuraCostoItem.Insumo.descripcion,
                         idComparativo = a.idComparativo,
                         idEstructuraCostoItem = a.idEstructuraCostoItem.Value,
                         idInternal = a.idInternal,
                         idMonedaBase = a.idMonedaBase.Value,
                         idPadre = a.idPadre,
                         monedaBase = a.Moneda.descripcion,
                         nivel = a.nivel.Value,
                         precio1 = a.precio1.Value,
                         
                         precio2 = a.precio2.Value,
                         
                         precio3 = a.precio3.Value,
                         
                         precioBase = a.precioBase.Value,
                         precioBaseMon = string.Format("{0} {1:N4}", a.Moneda.simbol, a.precioBase.Value),
                         simbol1 = a.Comparativo.Moneda.simbol,
                         
                         simbolBase = a.Moneda.simbol,
                         tipoCambio = a.tipoCambio.Value,
                         tipoCambioECItem = a.tipoCambioOrig.Value,
                         tipoCambioOrig = a.tipoCambioOrig.Value,
                         total1 = a.total1.Value,
                         total2 = a.total2.Value,
                         total3 = a.total3.Value,
                         
                         unidad = a.EstructuraCostoItem.Insumo.InsumoUnidad.abreviacion,
                         
                         //lo que se trae  desde EstructuraCostoItem actual

                         //---------cantidades

                         cantidadBase = a.cantidadBase.Value,
                         cantidadDisp = a.cantidadBase.Value - a.cantUso.Value,
                         
                         cantUso = a.cantUso.Value,
                         //-----------------
                        
                         totalCantidadOrig = a.totalCantidadOrig.Value,
                         totalDisp = a.totalBase.Value - a.totalUso.Value,
                         totalMonedaBase = a.totalMonedaBase.Value,
                         totalUso = a.totalUso.Value,

                         totalBaseMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
                         totalBaseOrigen = a.totalBaseOrigen.Value,

                         totalComparar = a.totalBase.Value,
                         totalCompararMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalBase.Value),
                         //---------------------------- para los casos de item finalizados  TOTAL SALDOS
                         totalBaseOrig = (a.bitFinalizado.Value | a.cantUso>0) ? a.totalBaseOrigen.Value :
                                            ((a.EstructuraCostoItem.total - a.EstructuraCostoItem.totalUso) * a.tipoCambioOrig / a.tipoCambio).Value,

                         totalBaseMonOrig = (a.bitFinalizado.Value | a.cantUso > 0) ? string.Format("{0} {1:N4}", a.Moneda.simbol, a.totalBaseOrigen.Value) :
                                            string.Format("{0} {1:N4}", a.Moneda.simbol, (a.EstructuraCostoItem.total-a.EstructuraCostoItem.totalUso)*a.tipoCambioOrig/a.tipoCambio.Value),


                         totalBaseMonOrigen = (a.bitFinalizado.Value | a.cantUso > 0) ? string.Format("{0} {1:N4}", a.Moneda.simbol, a.totalBaseOrigen.Value) : 
                                            string.Format("{0} {1:N4}", a.Moneda.simbol, (a.EstructuraCostoItem.total - a.EstructuraCostoItem.totalUso) * a.tipoCambioOrig / a.tipoCambio.Value),

                         cantidadOrig = (a.bitFinalizado.Value | a.cantUso > 0) ? a.totalCantidadOrig.Value :
                                        (a.EstructuraCostoItem.cantidad.Value-a.EstructuraCostoItem.cantidadUso).Value,//EC
                            
                         //------------
                        //-----------BASES para el calculo base

                            totalBase = a.totalBase.Value,
                         TotalBaseMonBase = (a.bitFinalizado.Value | a.cantUso > 0) ? a.totalBaseOrigen.Value : 
                         ((a.EstructuraCostoItem.total-a.EstructuraCostoItem.totalUso)*a.tipoCambioOrig/a.tipoCambio).Value,
                         

                        //-------------------------------

                         bitFinalizado = a.bitFinalizado.Value,
                     };

            return q2.ToList();


        }
    
        public ComparativoItemInfo GetCompartivoItemFromEComprasItem(int idEstructuraComprasItem,
                                                                int idMonedaComparativo)
        {


            EstructuraCostoItem ECItem =
             DbUtil.Db.EstructuraCostoItems.Single(p => p.idInternal == idEstructuraComprasItem);
            

            //--- para el caso de  tipo de combio de la obra-regla de negocio------------

            decimal tipoCambioComparativo = 1;
            if (idMonedaComparativo == 4)
            {
                tipoCambioComparativo =ECItem.EstructuraCosto.Obra.tipoCambio.Value;
                        
            }
            //----------------------------------------------------------------------------
            
               Moneda monedaComparativo = DbUtil.Db.Monedas.Single(p => p.idInternal == idMonedaComparativo);
            
            
            ComparativoItemInfo comparativoItem = new ComparativoItemInfo();

                // si la moneda del comparativo es igual  a la estructura conserva los valores del ecitem.
            
            
            decimal total = (ECItem.total - ECItem.totalUso - ECItem.totalReUso).Value;
            if (total < 0) { total = 0; }



                if (ECItem.idMoneda != idMonedaComparativo)
                {
                    // si  $1  a soles es S/3.5
                    //  1 * TC=3.5 -->  1*3.5/ 1
                    // si  S/1 a dolares es  1/ 3.5
                    // 1/3.5-->    1* 1/3.5=
                    // traemos la  informacion de monedaBase

                    //Moneda monedaBase = DbUtil.Db.Monedas.Single(p => p.idInternal == 3);


                    // trameos la informacion para moneda Estrcutura de compras item

                    Moneda monedaEComprasitem = DbUtil.Db.Monedas.Single(p => p.idInternal == ECItem.idMoneda);
                    decimal calculado = 0;
                    if (total != 0)
                    {
                        calculado = Math.Round(((ECItem.total.Value - ECItem.totalUso.Value) * ECItem.tipoCambio.Value) / tipoCambioComparativo, 4);
                    }
                    
                    ///primero lo convertimos a su basico y luego  convertimos al tipo de cambio que necesitamos
                    comparativoItem.precioBase = Math.Round((ECItem.precio.Value * ECItem.tipoCambio.Value) / tipoCambioComparativo, 4);
                    comparativoItem.totalBase = calculado;
                    comparativoItem.totalComparar = calculado;
                    comparativoItem.totalBaseOrig = calculado;
                    comparativoItem.simbolBase = monedaEComprasitem.simbol;
                    comparativoItem.idMonedaBase = monedaEComprasitem.idInternal; ;
                    comparativoItem.tipoCambio = tipoCambioComparativo;
                    //este tipo de cambio es importante para conservar el valor de la estructura, si cambia la moneda y no presetar
                    //informacion desigual por el tipo de cambio
                }
                else
                {
                  
                    comparativoItem.precioBase = ECItem.precio.Value;
                    comparativoItem.totalBase =     total;
                    comparativoItem.totalComparar = total;
                    comparativoItem.totalBaseOrig = total;
                    comparativoItem.simbolBase = ECItem.Moneda.simbol;
                    comparativoItem.idMonedaBase = ECItem.idMoneda.Value; //de la Estructura de compras
                    comparativoItem.tipoCambio = ECItem.tipoCambio.Value;
                }

                //por   default es 
                //if (ECItem.bitControlCant == null)
                //{
                //    comparativoItem.bitControlCantOrig = false;
                //}
                comparativoItem.bitControlCantOrig = ECItem.bitControlCant;

                if (ECItem.unidad.ToUpper().Trim() == "GLB")
                {
                    comparativoItem.bitControlCantOrig = false;
                }

                comparativoItem.idInternal = Parametros.GenerarID();
                comparativoItem.bitControlCant = false;

                comparativoItem.idEstructuraCostoItem = ECItem.idInternal;

                Insumo insumo = DbUtil.Db.Insumos.Single(p => p.idInternal == ECItem.idInsumo);

                comparativoItem.codigo = insumo.codigo;
                comparativoItem.descripcion = insumo.descripcion;
                comparativoItem.unidad = insumo.InsumoUnidad.abreviacion;

                comparativoItem.cantidadBase = ((ECItem.cantidad - ECItem.cantidadUso).Value < 0) ? 0 : (ECItem.cantidad - ECItem.cantidadUso).Value;
                comparativoItem.cantidadOrig = comparativoItem.cantidadBase; //(ECItem.cantidad - ECItem.cantidadUso).Value;
                comparativoItem.tipoCambioOrig = ECItem.tipoCambio.Value;

                comparativoItem.precio1 = 0;
                comparativoItem.total1 = 0;
                comparativoItem.precio2 = 0;
                comparativoItem.total2 = 0;
                comparativoItem.precio3 = 0;
                comparativoItem.total3 = 0;
                comparativoItem.totalUso = 0; //importante para verificar la modificacion
                comparativoItem.nivel = 0;
                comparativoItem.idPadre = 0;
                comparativoItem.simbol1 = comparativoItem.simbolBase;
                

                comparativoItem.bitSel = true;
             
                
                comparativoItem.precioBaseMon = comparativoItem.simbolBase + " " + comparativoItem.precioBase.ToString();
                comparativoItem.totalBaseMon = comparativoItem.simbolBase + " " + comparativoItem.totalBase.ToString();
                comparativoItem.totalCompararMon = comparativoItem.simbolBase + " " + comparativoItem.totalComparar.ToString();
                comparativoItem.totalBaseMonOrig = comparativoItem.simbolBase + " " + comparativoItem.totalBaseOrig.ToString();
                comparativoItem.idOrdenCompratemRef = ECItem.idOrdenCompraItemRef == null ? 0 : ECItem.idOrdenCompraItemRef.Value;

                return comparativoItem;
          

        }

        public ComparativoItemInfo GetComparativoItemAddOCItem(ComparativoItemInfo Citem,bool InclIGV,int itemColProv)
        {

            OrdenCompraItem OCItem = DbUtil.Db.OrdenCompraItems.Single(p => p.idInternal == Citem.idOrdenCompratemRef);

            if (itemColProv == 1)
            {
                Citem.precio1 = InclIGV ? OCItem.precioInclIGV.Value : OCItem.precioNoIGV.Value;
                Citem.total1 = InclIGV ? OCItem.subMontoIGV.Value : OCItem.subMonto.Value;
                Citem.simbol1 = OCItem.OrdenCompra.Moneda1.simbol;
            }
            if (itemColProv ==2)
            {
                Citem.precio2 = InclIGV ? OCItem.precioInclIGV.Value : OCItem.precioNoIGV.Value;
                Citem.total2= InclIGV ? OCItem.subMontoIGV.Value : OCItem.subMonto.Value;
                Citem.simbol1 = OCItem.OrdenCompra.Moneda1.simbol;
            }

            if (itemColProv == 3)
            {
                Citem.precio3 = InclIGV ? OCItem.precioInclIGV.Value : OCItem.precioNoIGV.Value;
                Citem.total3 = InclIGV ? OCItem.subMontoIGV.Value : OCItem.subMonto.Value;
                Citem.simbol1 = OCItem.OrdenCompra.Moneda1.simbol;
            }

                                    


            return Citem;

        }

            public ComparativoInfo LoadComparativo(int idComparativo)
        {


            var q = from a in DbUtil.Db.Comparativos
                    where a.idInternal == idComparativo
                    select new ComparativoInfo
                    {
                        descripcion = a.descripcion,
                        estado = a.GrupoDatoitem.descripcion,
                        estructura = a.EstructuraCosto.Estructura.descripcion,
                        estructuraCosto = a.EstructuraCosto.descripcion,
                        fecha = a.fecha.Value,
                        idEstado = a.idEstado.Value,
                        idEstructuraCosto = a.idEstructuraCosto.Value,
                        idObra = a.idObra.Value,
                        moneda = a.Moneda.descripcion,
                        numDocumento = a.numDocumento,
                        observaciones = a.Observaciones,
                        simbol = a.Moneda.simbol,
                        tipoCambio = a.tipoCambio,
                        totalBaseMon = a.totalBase.Value,
                        totalComparativoMon = a.totalComparativo.Value,
                        totalUsoEnOrdenCompraMon = a.getMontoUsoTotal(DbUtil.Db, idComparativo),
                        aprobacion2 = a.Empleado2.descripcion,
                        aprobacion1 = a.Empleado3.descripcion,
                        fechaMod = a.fechaMod.Value,
                        fechaCre = a.fechacre.Value,
                        fechaAprobacion2 = a.fechaAprob,
                        idMoneda = a.idMoneda.Value,
                        usuarioCre=a.Empleado.descripcion,
                       ProveedorSelec=a.idProveedorSelec,
                       obra=a.Obra.descripcion,
                       idInternal=a.idInternal

                    };
                return q.First();


        }



        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<ComparativoProveedorInfo> getComparativoProveedorInfo(int idComparativo)
        {


            var q = from a in DbUtil.Db.ComparativoProveedors
                    where a.idComparativo == idComparativo
                    select new ComparativoProveedorInfo
                    {
                        idInternal = a.idinternal,
                        descripcion = a.Proveedor.descripcion,
                        bitSeleccion = a.bitSeleccion.Value,
                        condicion = a.condicion,
                        formaPago = a.FormaPago.descripcion,
                        idComparativo = a.idComparativo.Value,
                        idFormaPago = a.idFormaPago.Value,
                        idMoneda = a.idMoneda.Value,
                        idProveedor = a.idProveedor.Value,
                        item = a.item.Value,
                        moneda = a.Moneda.descripcion,
                        NroProveedor = string.Format("{0}{1}", "Proveedor", a.item.ToString()),
                        simbol = a.Moneda.simbol,
                        tipoCambio = a.tipoCambio.Value,

                        total = a.total.Value,
                        totalMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.total),

                        totalContratado = a.totalContratado.Value,
                        totalContrMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalContratado),

                        TotalDisponible = a.totalContratado.Value - a.totalUso.Value,
                        totalDispMon = string.Format("{0} {1:N}", a.Moneda.simbol, (a.totalContratado - a.totalUso).Value),

                        totalUso = a.totalUso.Value,
                        totalUsoMon = string.Format("{0} {1:N}", a.Moneda.simbol, a.totalUso.Value),

                    };

            return q.ToList();

            //var q=from a in DbUtil.Db.ComparativoProveedors
            //            where a.idComparativo == idComparativo
            //            select new ComparativoProveedorInfo
            //            {
            //                idInternal = a.idinternal,
            //                descripcion = a.Proveedor.descripcion,
            //                bitSeleccion=a.bitSeleccion.Value,
            //                condicion=a.condicion,
            //                formaPago=a.FormaPago.descripcion,
            //                idComparativo=a.idComparativo.Value,
            //                idFormaPago=a.idFormaPago.Value,
            //                idMoneda=a.idMoneda.Value,
            //                idProveedor=a.idProveedor.Value,
            //                item=a.item.Value,
            //                moneda=a.Moneda.descripcion,
            //                NroProveedor=string.Format("{0}{1}","Proveedor",a.item.ToString()),
            //                simbol=a.Moneda.simbol,
            //                tipoCambio=a.tipoCambio.Value,
                            
            //                //total de los comparativositem segun item1,2,3 del proveedor , no cambiar
            //                total=a.total.Value,
            //                totalMon=string.Format("{0} {1:N}",a.Moneda.simbol, a.total),
            //                //Total Base del comparativo,el del E/C

            //                totalBaseMon=string.Format("{0} {1:N}",a.Comparativo.Moneda.simbol,a.Comparativo.totalBase.Value),
            //                // al generar la seleccion del proveedor
            //                totalContratado=a.totalContratado.Value,
            //                totalContrMon=string.Format("{0} {1:N}",a.Moneda.simbol, a.totalContratado),
                            
            //                TotalDisponible=a.totalContratado.Value-a.totalUso.Value,
            //                totalDispMon=string.Format("{0} {1:N}",a.Moneda.simbol,(a.totalContratado-a.totalUso).Value),
 
            //                totalUso=a.totalUso.Value,
            //                totalUsoMon=string.Format("{0} {1:N}",a.Moneda.simbol,a.totalUso.Value),
            //                totalDevueltoMon = string.Format("{0} {1:N}",a.Moneda.simbol,a.ComparativoItemSelecPrvs.Sum(p=>p.total)-a.Comparativo.totalBase.Value),
                            
            //            };

            //    return q.ToList();
        }



    [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<ComparativoItemSelecInfo> getComparativoItemSelec(int idEstructuraCostoItem)
        {


            var q = from a in DbUtil.Db.ComparativoItemSelecPrv
                    where a.ComparativoItem.idEstructuraCostoItem == idEstructuraCostoItem
                    select new ComparativoItemSelecInfo
                    {
                        codDescripcion=String.Format("{0}-{1}",a.ComparativoItem.codigo,a.ComparativoItem.descripcion),
                       cantidad=a.cantidad.Value,
                       cantidadUso=a.cantidadUso.Value,
                       
                       numDocumento=String.Format("COMP:{0}",a.ComparativoItem.Comparativo.numDocumento),
                       tipoCambio=a.ComparativoItem.Comparativo.tipoCambio,
                       precio=String.Format("{0}{1:N}",a.ComparativoItem.Comparativo.Moneda.simbol,a.precio.Value),
                       total=String.Format("{0}{1:N}",a.ComparativoItem.Comparativo.idMoneda,a.total.Value),
                       totalUso=String.Format("{0}{1:N}",a.ComparativoItem.Comparativo.idMoneda,a.totalUso.Value),

                    };

            return q.ToList();

        }




    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public List<ComparativoDevItemInfo> GetComparativoDevItemFromComparativo(int idComparativo, string orderBy = default(string))
    {
        // no debe cambiar el proveedor  en el mismo comparativo

        var q = from a in DbUtil.Db.ComparativoItems
                where a.idComparativo == idComparativo
                & a.ComparativoItemSelecPrvs.Sum(p=>p.totalUso) > 0
               // & a.bitFinalizado==false
                & a.totalBaseOrigen.Value-a.ComparativoItemSelecPrvs.Sum(w => w.totalUso) > 0
                select new ComparativoDevItemInfo
                {
                    Codigo = a.codigo,
                    descripcion = a.descripcion,
                    idInternal = a.idInternal,
                    totalBaseStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalBaseOrigen),
                    totalBase = a.totalBaseOrigen.Value,
                    totalContratado=a.ComparativoItemSelecPrvs.Sum(e=>e.total.Value),
                    
                    totalContratadoStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.ComparativoItemSelecPrvs.Sum(e => e.total.Value)),
                    
                    totalOC = a.ComparativoItemSelecPrvs.Sum(e => e.totalUso.Value),
                    totalOCStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalUso),
                    unidad = a.unidad,

                    disponibleStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalBaseOrigen.Value - a.ComparativoItemSelecPrvs.Sum(e => e.totalUso.Value)),
                    disponible = a.totalBaseOrigen.Value - a.ComparativoItemSelecPrvs.Sum(e => e.totalUso.Value),
                };

        q = ApplySortG(q, orderBy);

        return q.ToList();
    }

    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public string getComparativoDescripcion(string prefixText, int count,int idObra)
    {
        
        var q = (from a in DbUtil.Db.Comparativos
                where a.idObra ==idObra
                & a.descripcion.Contains(prefixText)
                 select a.descripcion).Distinct().Take(count);
        
        return Util.Tbl2Str(Util.EntidadToDataTable(q));

    }
    


    [DataObjectMethod(DataObjectMethodType.Select, false)]
    public List<ComparativoDevolucionInfo> GetComparativoDevoluciones(int idComparativo, 
                                                                int startRowIndex, 
                                                                int maximumRows, 
                                                                string sortExpression)
    {
        // no debe cambiar el proveedor  en el mismo comparativo

        var q = from a in DbUtil.Db.ComparativoDevolucions
                where a.idComparativo == idComparativo
                select new ComparativoDevolucionInfo
                {
                    fecha = a.fecha,
                    fechaStr = a.fecha.ToShortDateString(),
                    idInternal = a.idInternal,
                    idmotivo = a.idmotivo,
                    motivoStr =a.MotivoItem.descripcion,
                    usuarioCre = a.usuarioCre.ToString(),
                    totalAprov = a.totalAprov,
                    totalAprovStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalAprov),
                    totalBaseAprov = a.totalBaseAprov,
                    totalBaseAprovStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalBaseAprov),
                    totalBaseItemStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalBaseItem),
                    totalDevolucionStr = string.Format("{0} {1:N}", a.Comparativo.Moneda.simbol, a.totalDevolucion),
                    
                };

        _count = q.Count();
        q = ApplySort(q, sortExpression);
       
        return q.Skip(startRowIndex).Take(maximumRows).ToList();

       
    }


   

        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public List<ComparativoRpt> loadComparativoRPT(int idcomparativoProveedor)
        {

             ComparativoProveedor comparaProv= DbUtil.Db.ComparativoProveedors.Single(p => p.idinternal == idcomparativoProveedor);
            
            string archivoLogo=comparaProv.Comparativo.Obra.Proyecto.Empresa.Logo.ToString();
            string archivoFirma = String.Empty;
            if (comparaProv.Comparativo.Empleado2 != null)
            {
                archivoFirma = comparaProv.Comparativo.Empleado2.firma.ToString();
            }

            if (archivoLogo.Trim() == String.Empty)
            {
                throw new Exception("No existe logo de la Empresa");
            }
            if (archivoFirma.Trim() == String.Empty)
            {
                throw new Exception("No existe Firma del Usuario");
            }
            
            
            string rutaLogo = System.Web.HttpContext.Current.Server.MapPath("../App_Data/Empresa/Logo/" + archivoLogo);
            string rutaFirma = System.Web.HttpContext.Current.Server.MapPath(string.Format("../App_Data/Empleado/Firma/{0}/{1}", comparaProv.Comparativo.Empleado2.idInternal, archivoFirma));
            
            byte[] imagen = UtilityExtensions.Util.FileToBytesImage(rutaLogo);
            byte[] imagenAprob2 = UtilityExtensions.Util.FileToBytesImage(rutaFirma);

            var q= from a in DbUtil.Db.ComparativoItemSelecPrv
                   where a.idComparativoProv == idcomparativoProveedor
                   select new ComparativoRpt
                        {
                       actividad=a.ComparativoItem.Comparativo.Obra.TipoObra.descripcion,
                       aprobador1 = a.ComparativoItem.Comparativo.Empleado.descripcion,
                     
                       aprobador2=imagenAprob2,
                       cantidad = String.Format("{0:N}", a.ComparativoItem.cantidadBase.Value),
                       cantidadBase = String.Format("{0:N}", a.ComparativoItem.totalCantidadOrig.Value),
                       centroCosto = a.ComparativoItem.Comparativo.Obra.centroCosto,
                       condiciones = a.ComparativoProveedor.condicion,
                       contacto=a.ComparativoProveedor.Proveedor.contacto,
                       descripcionInsumo=a.ComparativoItem.descripcion,
                       direccionObra=a.ComparativoItem.Comparativo.Obra.direccion,
                       fecha=a.ComparativoItem.Comparativo.fecha.Value.ToShortDateString(),
                       fechaAprob1 = a.ComparativoItem.Comparativo.fechaRevisor.Value.ToShortDateString(),
                       fechaAprob2 = a.ComparativoItem.Comparativo.fechaAprob.Value.ToShortDateString(),
                       fechaContrato = a.ComparativoItem.Comparativo.fecha.Value.ToShortDateString(),
                       fechaCotizacion = a.ComparativoItem.Comparativo.fecha.Value.ToShortDateString(),
                       msgincluyeIGV=(a.ComparativoItem.Comparativo.Obra.incluyeIGV==true)?"INCLUYE IGV":"NO INCLUYE IGV",
                       numDocumento=a.ComparativoItem.Comparativo.numDocumento,
                       obra=a.ComparativoItem.Comparativo.Obra.descripcion,
                       observaciones=a.ComparativoItem.Comparativo.Observaciones,
                       precioBase= String.Format("{0:N}", a.ComparativoItem.precioBase.Value),
                       precioUnit= String.Format("{0:N}", a.precio.Value),
                       proveedor=a.ComparativoProveedor.Proveedor.descripcion,
                       referencia=a.ComparativoItem.Comparativo.EstructuraCosto.descripcion,
                       telefono=a.ComparativoProveedor.Proveedor.telefonoOficina1,
                       total= String.Format("{0:N}", a.total.Value),
                       totalBase= String.Format("{0:N}", a.ComparativoItem.totalBaseOrigen.Value),
                       unidad=a.ComparativoItem.unidad,
                       LogoEmpresa=imagen,
                       idEstado=a.ComparativoItem.Comparativo.idEstado.Value,
                       totalComparativo=a.ComparativoProveedor.total.Value,
                       totalBasePresupuesto=a.ComparativoItem.Comparativo.totalComparativo.Value,
                       simbolMon=a.ComparativoItem.Comparativo.Moneda.simbol,
                      
                       totalRealConsumo =
                       (a.ComparativoItem.Comparativo.idEstado == 14 ? a.ComparativoProveedor.totalContratado.Value : a.ComparativoProveedor.total.Value)
                     };
                     var fr = from a in DbUtil.Db.RecepcionDocs
                     where a.OrdenCompra.idProveedorSelec== idcomparativoProveedor
                     select new RecepcionDocSaldoInfo
                     {
                         Tipodocumento=String.Format("FR-{0}",a.numRecepcion),
                         //no incluye IGV / segun el comparativo
                         importe = (a.Obra.incluyeIGV == true) ? a.totalMonOrig.Value :(a.idmoneda==4?a.netoMN.Value/a.tipoCambio.Value:a.netoMN.Value),
                         importeStr = (a.Obra.incluyeIGV == true) ? String.Format("{0:N}", a.totalMonOrig.Value) : 
                         (a.idmoneda == 4 ? String.Format("{0:N}", a.netoMN.Value / a.tipoCambio.Value) : String.Format("{0:N}", a.netoMN.Value)),
                     };


            //quien tiene mayor cantidad de registros
            List<RecepcionDocSaldoInfo> ListaRecepcion=fr.ToList();
            List<ComparativoRpt> ListacomparativoRpt=q.ToList();

            decimal saldo = comparaProv.totalContratado.Value;
            decimal totalImporte = ListaRecepcion.Sum(p => p.importe);
            //--------------------
            if (ListaRecepcion.Count()>ListacomparativoRpt.Count())
            {
                // creamos adicionaesl lista comparativoRPT para recorrerlo
               
                int totatXAdicionar = ListaRecepcion.Count() - ListacomparativoRpt.Count();

                for (int i = 0; i < totatXAdicionar; i++)
                {
                    ComparativoRpt nuevo = new ComparativoRpt();

                    nuevo = (ComparativoRpt)ListacomparativoRpt.First().Clone();

                    nuevo.cantidad = "";
                    nuevo.unidad ="";
                    nuevo.descripcionInsumo = "";
                    nuevo.precioUnit = "";
                    nuevo.total = "";
                    nuevo.totalBase="";
                    nuevo.precioBase = "";
                    nuevo.cantidadBase = "";
                    ListacomparativoRpt.Add(nuevo);
                }
            }
            else{
                int totatXAdicionar = ListacomparativoRpt.Count() - ListaRecepcion.Count() ;

                for (int i = 0; i < totatXAdicionar; i++)
                {
                    RecepcionDocSaldoInfo nuevo = new RecepcionDocSaldoInfo();
                    
                    ListaRecepcion.Add(nuevo);
                }

            }
            //---------------------------
                //existe mayor cantidad de FR que item en el comparativo
                // debido a que existe mayor FR /  agregamos item vacios
    
                for (int i = 0; i < ListacomparativoRpt.Count; i++)
                {
                    saldo = saldo - ListaRecepcion[i].importe;
                    ListacomparativoRpt[i].recepcionDoc = ListaRecepcion[i].Tipodocumento;
                    ListacomparativoRpt[i].importe = ListaRecepcion[i].importeStr;
                    if (ListacomparativoRpt[i].importe !=null)
                        ListacomparativoRpt[i].saldo = String.Format("{0:N}",saldo);
                      
                    ListacomparativoRpt[i].totalImporte=totalImporte;
                    ListacomparativoRpt[i].totalsaldo = comparaProv.totalContratado.Value - totalImporte;
                }

            return ListacomparativoRpt;
            }
    //        public void  mantenimeintoComparativoProveedor()
    //        {
    //var q= from a in DbUtil.Db.ComparativoProveedors
    //       select a;

    //foreach (var item in q)
    //{
    //    decimal total = item.getMontoTotal(DbUtil.Db);
    //    item.total = total;
    //    DbUtil.Db.SubmitChanges();   
    //}


     
    //        }
        }
    


 
}